/** @file ADE7763.cpp
 *  @author Lukáš Michalík
 *  @version 1.0.0
 *  @date 16.4.2013
 *
 */

/* Includes ------------------------------------------------------------------*/

//#include <iostream.h>
#include "wiringPiSPI.h"
//#include "stdio.h"

#include "wiringPi.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdint.h"
#include "errno.h"
#include "string.h"
#include "ADE7763.hpp"
#include "HelloWorld.hpp"

/** @addtogroup RaspBerryPi_Power_Control
  * @{
  */

/** @defgroup ADE_7763
  * @brief ADE_7763 driver modules
  * @{
  */


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup ADE7763_Private_Functions
  * @{
  */

/**
 * @brief Čtení/zápis z/do ADE 7763. Nejedná se o low level funkci.
 * Vyvolá čtení nebo zápis z/do ADE7763 po SPI.
 * Podle zvoleného modu upraví adresu jako zapisvací nebo čtecí.
 * @param kanal Určuje SPI kanál.
 * 	@arg 1: Aktivuje CE 1.
 * 	@arg 0: Aktivuje CE 0.
 * @param buffer ukazatel na pole, první položka adresa,
 * další čtená nebo zapsaná data.
 * @param mode Specifikuje prováděnou operaci.
 * 	@arg SPIREAD: Čtení
 * 	@arg SPIWRITE: Zápis
 * @param verbose Přepíná mezi rozšířeným textovým výstupem (debug mod) a klasickým textovým výstupem (žádný nebo minimální).
 * 	@arg 1: Podá rozšířený textový výstup
 * 	@arg 0: Podá základní textový výstup.
 * @return           default 0
 *
 *  @verbatim
 *  ================================================
 *  | prescaler	| 	Frekvence  						|
 *  ================================================
 *  | 2			| 	125 MHz							|
 *  | 4       	| 	62.5 MHz						|
 *  | 8			|	31.2 MHz						|
 *  | 16      	|	15.6 MHz						|
 *  | 32       	|	7.8 MHz maximum pro ADE7763		|
 *  | 64       	|	3.9 MHz							|
 *  | 128     	|	1953 kHz						|
 *  | 256      	|	976 kHz							|
 *  | 512      	|	488 kHz							|
 *  | 1024     	|	244 kHz							|
 *  | 2048     	|	122 kHz							|
 *  | 4096		|	61 kHz							|
 *  | 8192    	|	30.5 kHz						|
 *  | 16384   	|	15.2 kHz						|
 *  | 32768   	|	7629 Hz							|
 *  ================================================
 *  @endverbatim
*/
int ade7763ReadWrite(uint8_t kanal, uint8_t* buffer, uint8_t mode,
		uint8_t verbose) {

	uint16_t Regtmp;
	Regtmp = buffer[0];												//odložení původní hodnoty registru přijaté z nadřazené funkce
	uint8_t Datatmp[MaxBuffSize];
	uint8_t bufsize;
	buffer[0] = buffer[0] & 0x3f;									//vymaskování maximální adresy registru
	uint8_t i;
	Datatmp[0] = Regtmp;

	if (RegLength[Regtmp - 1] <= 8)									//nastavení počtu odesílaných slov
		bufsize = 1;
	else if (RegLength[Regtmp - 1] <= 16)
		bufsize = 2;
	else
		bufsize = 3;

	if (verbose) {

		//ukecaný mód
		printf("%3s register %2x in ADE7763 CS SPI%d  \n", SpiMode[mode],
				Regtmp, kanal);
		if (mode == SPIWRITE) {
			wiringPiSPIDataRW(kanal, Datatmp, bufsize + 1);			//přečte register a adresou v buffer[0] zapíše na další pozice v registru
			PRINT_REGISTE_TABLE_HEAD;								//vytiskne popisky (záhlaví) pro výpis registru
			PrintRegisterTableLine(Datatmp, bufsize, Regtmp);		//vytiskne údaje o zvoleném registru -- poslední položka

			buffer[0] = 0x80 + buffer[0];							//nastavení příznaku zápisu

			printf("zápis... \n");
			wiringPiSPIDataRW(kanal, buffer, bufsize + 1);
			CLEAN_POLE(MaxBuffSize, Datatmp);
			Datatmp[0] = Regtmp;

			wiringPiSPIDataRW(kanal, Datatmp, bufsize + 1);
			PrintRegisterTableLine(Datatmp, bufsize, Regtmp);		//vytiskne údaje o zvoleném registru -- poslední položka

		} else if (mode == SPIREAD) {
			wiringPiSPIDataRW(kanal, buffer, bufsize + 1);			//přečte register a adresou v buffer[0] zapíše na další pozice v registru
			PRINT_REGISTE_TABLE_HEAD;								//vytiskne popisky (záhlaví) pro výpis registru
			PrintRegisterTableLine(buffer, bufsize, Regtmp);		//vytiskne údaje o zvoleném registru -- poslední položka
		} else
			exit(1);
	} else {
		//silent mód
		if (mode == SPIWRITE) {
			buffer[0] = 0x80 + buffer[0];							//nastavení příznaku zápisu
			wiringPiSPIDataRW(kanal, buffer, bufsize + 1);
			CLEAN_POLE(MaxBuffSize, Datatmp);

		} else if (mode == SPIREAD) {
			wiringPiSPIDataRW(kanal, buffer, bufsize + 1);			//přečte register a adresou v buffer[0] zapíše na další pozice v registru
		//	if (bufsize >= 1)
				//printf(" 0x%2x", buffer[1]);
		//	if (bufsize >= 2)
				//printf(" %2x", buffer[2]);
		//	if (bufsize == 3)
				//printf(" %2x", buffer[3]);
			//printf(" \n");
		} else
			exit(1);
	}

	return 0;

}

/**
 * @brief Vypíše jeden řádek inoformací o dotazovaném registru.
 * @param buffer Ukazatel na pole, první položka adresa,
 * další čtená nebo zapsaná data.
 * @param bufsize Vztahuje se k počtu bitů v registru, busize je 1, 2 nebo 3.
 * Určuje s kolika byty se bude pracoavt a kolik položek se vypíše.
 * @param Regtmp Adresa registru, ze kterého se budou číst data.
 * @return  none
 */
void PrintRegisterTableLine (uint8_t* buffer,uint8_t bufsize, uint8_t Regtmp ) {
	printf("%2x     | %10s | %5d | %3s | %d |", Regtmp, list[Regtmp],
    							RegLength[Regtmp - 1], RegPermmision[Regtmp - 1], bufsize);
    		if (bufsize >= 1)
    						printf(" 0x%2x", buffer[1]);
    					if (bufsize >= 2)
    						printf(" %2x", buffer[2]);
    					if (bufsize == 3)
    						printf(" %2x", buffer[3]);
    					printf(" \n");

}



/**
 * @brief Vyčte všechny registry ADE 7763 a zobrazí je v četně detailního popisu.
 * @param kanal Kanál SPI 1 nebo 0.
 * @return  none
 */
void ade7763ReadAll(int kanal) {


	uint8_t bufsize = 0;
	uint8_t buffer[MaxBuffSize];
	uint8_t i = 0;
	uint16_t reg = 1;

	printf("Read all registers ADE7763 CS SPI%d \n", kanal);
	printf("ADRESA |    NAME    | DELKA | PER | W |    DATA    |    DESCRIPTION  \n");
	printf("_____________________________________________________________________\n");

	while (reg <= POCET_REGISTRU_ADE7763) {
		buffer[0] = reg & 0x3f;
		for (i = 1; i < MaxBuffSize; i++)
			buffer[i] = 0x00;

		if (RegLength[reg - 1] <= 8)
			bufsize = 1;
		else if (RegLength[reg - 1] <= 16)
			bufsize = 2;
		else
			bufsize = 3;

		if (buffer[0] != 0x08 && buffer[0] != 0x28 && buffer[0] != 0x29
				&& buffer[0] != 0x2A && buffer[0] != 0x2B && buffer[0] != 0x2C
				&& buffer[0] != 0x2D && buffer[0] != 0x2E && buffer[0] != 0x2F
				&& buffer[0] != 0x30 && buffer[0] != 0x31 && buffer[0] != 0x32
				&& buffer[0] != 0x33 && buffer[0] != 0x34 && buffer[0] != 0x35
				&& buffer[0] != 0x36 && buffer[0] != 0x37 && buffer[0] != 0x38
				&& buffer[0] != 0x39 && buffer[0] != 0x3A && buffer[0] != 0x3B
				&& buffer[0] != 0x3C) {
			wiringPiSPIDataRW(kanal, buffer, bufsize + 1);
			printf("%2x     | %10s | %5d | %3s | %d |", reg, list[reg],
					RegLength[reg - 1], RegPermmision[reg - 1], bufsize);
			if (bufsize >= 1) {
				printf(" 0x%2x", buffer[1]);
				if (bufsize < 2)
					printf(" ----- |");
			}
			if (bufsize >= 2) {
				printf(" %2x", buffer[2]);
				if (bufsize < 3)
					printf(" -- |");
			}
			if (bufsize == 3)
				printf(" %2x |", buffer[3]);
			printf(" %s \n", RegDescription[reg - 1]);
		} else {
			printf("%2x     | %10s | RESERVED \n", reg, list[reg]);
		}

		reg++;

	}
	printf("\n\n");

//return 0;
}


/**
 * @brief Testovací funkce
 * @todo smazat tuto funkci
 * @param void
 * @return  none
 */
void ade7763WriteTest(void)
{
	int kanal = 1;
	uint8_t delka = 4;
	uint8_t outb[0];
	uint16_t reg = 0x1C;
	uint16_t delaytime = 550;
	//uint8_t kanal = SPI1;
	printf("Write register ADE7763 CS SPI %d  register %d\n",kanal,reg);
			outb[0] = 0x80 + reg;
			//outb[0] = 0x51;
			outb[1] = 0xAA;
			outb[2] = 0x00;
			outb[3] = 0x00;

			wiringPiSPIDataRW(kanal, outb, delka);
			printf("%2x     | %10s | %2x %2x %2x %2x \n",reg,list[reg],outb[0],outb[1],outb[2],outb[3]);
			delayMicroseconds(delaytime);

			printf("\n\n");
	}

/**
 * @brief Testovací funkce
 * @todo smazat tuto funkci
 * @param void
 * @return  none
 */
void IrmsCalibrate(void)
{
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	long double  IrmsLSB,Irms;
	float napeti=5.0/10;

	uint32_t IrmMeasuredRAW;

	CLEAN_POLE(MaxBuffSize,Buffer);
	Buffer[0] = 0x16;
	ade7763ReadWrite(SPI1,Buffer, SPIREAD, 0);
	IrmMeasuredRAW = Buffer[1];
	IrmMeasuredRAW = IrmMeasuredRAW << 8 ;
	IrmMeasuredRAW = IrmMeasuredRAW + Buffer[2];
	IrmMeasuredRAW = IrmMeasuredRAW << 8 ;
	IrmMeasuredRAW = IrmMeasuredRAW + Buffer[3];

	IrmsLSB = napeti / IRMSMAXSCALE5;
	Irms = IrmsLSB * IrmMeasuredRAW;
	printf("%f/n",Irms);
//	printf("%f \n",pomoc);


}

/**
 * @brief Vypíše všechny status Flag ADE 7763.
 * @param void
 * @return  none
 */
void GetStatus7763(void) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint16_t RStatus;
	uint16_t OneLineStatus;
	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRSTATUS;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	RStatus = Buffer[1];
	RStatus = RStatus << 8;
	RStatus = RStatus + Buffer[2];

	for (i = 0; i < 16; i++) {
		OneLineStatus = RStatus & DvojkoveNasobky[i];
		if (OneLineStatus > 0)
			printf("flag 1 %s \n", InterupFlagsName7763[i]);
		else
			printf("flag 0 %s \n", InterupFlagsName7763[i]);

	}
}

/**
 * @brief Vypíše všechny status Flag ADE 7763. V určité chvíli se resetuje.
 * @todo Zjistit, kdy se registr nuluje.
 * @param void
 * @return  none
 */
void GetRstStatus7763(void) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint16_t RStatus;
	uint16_t OneLineStatus;
	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRRSTSTATUS;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	RStatus = Buffer[1];
	RStatus = RStatus << 8;
	RStatus = RStatus + Buffer[2];

	for (i = 0; i < 16; i++) {
		OneLineStatus = RStatus & DvojkoveNasobky[i];
		if (OneLineStatus > 0)
			printf("flag 1 %s \n", InterupFlagsName7763[i]);
		else
			printf("flag 0 %s \n", InterupFlagsName7763[i]);

	}
}

/**
 * @brief Vypíše naměřenou frekvenci. POZOR: zařízení musí být pod napětím 230V.
 * Když nedochází k průchodu napětí nulou, nedochází k žádnému měření.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  none
 */
float GetFrequency7763(uint8_t verbose) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint16_t Period;
	float TimePeriod;
	float Frekvency;
	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRPERIOD;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	Period = Buffer[1];
	Period = Period << 8;
	Period = Period + Buffer[2];

	TimePeriod = Period * LSBOFPERIOD;
	Frekvency = 1 / TimePeriod;
	if (verbose)
		printf("frekvence %f Hz \n", Frekvency);
	else
		printf("%f\n", Frekvency);

	return (Frekvency);

}

/**
 * @brief Podle vstupní proměnné aktivuje nebo deaktivuje měření teploty.
 * @param stav Deaktivace nebo aktivace měření teploty, 0 nebo 1.
 * @return  none
 */
void SetTemperature7763(uint8_t stav) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint16_t Mode;

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRMODE;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	Mode = Buffer[1];
	Mode = Mode << 8;
	Mode = Mode + Buffer[2];

	if (stav)
		Mode = Mode + DvojkoveNasobky[5];
	else
		Mode = Mode - DvojkoveNasobky[5];

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRMODE;
	Buffer[2] = Mode;
	Mode = Mode >> 8;
	Buffer[1] = Mode;

	ade7763ReadWrite(SPI1, Buffer, SPIWRITE, 0);
}

/**
 * @brief Vypíše naměřenou teplotu [°C]. POZOR: zařízení musí být pod napětím 230V.
 * Když nedochází k průchodu napětí nulou, nedochází k žádnému měření.
 * V rámci funkce dochází k inicializaci měření teploty.
 * @todo zavést průměrování naměřené teploty, popřípadě zjistit jestli to pomůže.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  Vrací změřenou hodnoty teploty.
 */
float GetTemperature7763(uint8_t verbose) {

	uint8_t Buffer[MaxBuffSize];
		uint8_t i;
		uint8_t Temperature;
		float Teplota;

		CLEAN_POLE(MaxBuffSize, Buffer);
		Buffer[0] = ADRTEMP;
		ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

		Temperature = Buffer[1];

		Teplota = Temperature * LSBOFTEMP + KOREKCETEPLOTY;

		if (verbose)
			printf("Teplota %f °C  +-25°C \n", Teplota);
		else
			printf("%f\n", Teplota);

return (Teplota);
}


/**
 * @brief Vypíše naměřenou hodnotu napětí Vrms [V]
 * @todo Zavést průměrování naměřené teploty, popřípadě zjistit jestli to pomůže.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  Vrací změřenou hodnoty napětí.
 */
float GetVrms7763(uint8_t verbose) {
			uint8_t Buffer[MaxBuffSize];
			uint8_t i;
			uint32_t VrmsData;
			float VrmsZaDelicem;
			float Vrms;
			float temp = 0;
			 static T_kruh_buffer Struct_Vrms;
			 //if (Struct_Vrms.pozice > 200);
			// Struct_Vrms.pozice = 0; // ošetření prvního běhu kdy může být v paměti cokoliv. Pozice bufferu je přeseune na 0

			if (!(GetFrequency7763(NON_VERBOSE_MODE) > 45 && GetFrequency7763(NON_VERBOSE_MODE) < 65) ) // když je bez napětí je detekovaná frekvence hodně velká (šum) tato podmínka zruší měření v takovémto případě.
			{
			if (verbose)
					{
			printf("Vrms 0 V\n");
				printf("Frekvence napětí mimo rozsah \n");
					}
			else
			printf("0\n");

			return (0);
			} // konec detekce je na napětí připojeno respektive je-li frekvence v mezích

			CLEAN_POLE(MaxBuffSize, Buffer);
			Buffer[0] = ADRVRMS;
			ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

			VrmsData = Buffer[1];
			VrmsData = VrmsData << 8;
			VrmsData = VrmsData + Buffer[2];
			VrmsData = VrmsData << 8;
			VrmsData = VrmsData + Buffer[3];


			VrmsZaDelicem = VRMSINSCALE / VRMSOUTSCALE * VrmsData + VRMSHRARDOFFSET  ; //maximální vstupní napětí / počtem hladin * naměřená hodnota
			Vrms = VrmsZaDelicem / VRMSBOCNIKR2 * (VRMSBOCNIKR1 + VRMSBOCNIKR2);


			//následuje průměrování, aktuální změřená hodnota se vezme a uloží do kruhového bufferu 200 prvků.
			Struct_Vrms.Prum_pole[Struct_Vrms.pozice] = Vrms;
			for (i=0;i<POCETPRUMEROVACICHCIKLU;i++)
			{
				temp = temp + Struct_Vrms.Prum_pole[i];
			}
			Vrms = temp / POCETPRUMEROVACICHCIKLU;

			if (Struct_Vrms.pozice < POCETPRUMEROVACICHCIKLU)
				Struct_Vrms.pozice ++;
			else
				Struct_Vrms.pozice = 0;

			// konec průměrování

			if (verbose)
				printf("Vrms %f V \n", Vrms);
			else
				printf("%f\n", Vrms);

			return (Vrms);

	}


void SetVrmsOS7763(uint16_t VrmsOS) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRVRMSOS;

	Buffer[2] = VrmsOS;
	VrmsOS = VrmsOS >> 8;
	Buffer[1] = VrmsOS;

	ade7763ReadWrite(SPI1, Buffer, SPIWRITE, 0);
}


/**
 * @brief Změří hodnotu proudu Irms [A]. Probýhá i průměrování.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  Vrací změřenou hodnoty proudu.
 */
float GetIrms7763(uint8_t verbose,uint8_t fast) {
			uint8_t Buffer[MaxBuffSize];
			uint8_t i; //je použito v clean buffer
			uint8_t j;
			uint32_t IrmsData;
			float IrmsNaBocniku;
			float Irms;
			uint32_t IrmsDataTable[RYCHLYPRUMER];
			float IrmsPrum = 0;

			for (j=0;j<RYCHLYPRUMER;j++)
			{
			CLEAN_POLE(MaxBuffSize, Buffer);
			Buffer[0] = ADRIRMS;
			ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

			IrmsData = Buffer[1];
			IrmsData = IrmsData << 8;
			IrmsData = IrmsData + Buffer[2];
			IrmsData = IrmsData << 8;
			IrmsData = IrmsData + Buffer[3];

			IrmsDataTable[j]= IrmsData;

			//if (fast)
			//delay(50);

			}
			for (j=0;j<RYCHLYPRUMER;j++)
			{
				IrmsPrum = IrmsPrum + IrmsDataTable[j];
			}
			IrmsPrum =IrmsPrum/RYCHLYPRUMER;

		/*	IrmsNaBocniku = IRMSINSCALE / IRMSOUTSCALE * IrmsPrum + IRMSHRARDOFFSET  ; //maximální vstupní napětí / počtem hladin * naměřená hodnota
			Irms = IrmsNaBocniku/RBOCNIK;

			if (verbose)
				printf("Irms %f A \n", Irms);
			else
				printf("%f\n", Irms);*/

	return (IrmsPrum);
	}

/**
 * @brief Nastaví vstupní rozsah proudového převodníku na 0.5V, 0.25V nebo 0.125V.
 * @param scale Výběr vstupního rozsahu 5 pro 0.5V, 25 pro 0.25V a 125 pro 0.125V.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  nome
 */
void SetScalePGA17763(uint8_t scale, uint8_t verbose) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint8_t GainPreset;
	uint8_t Gain;

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	GainPreset = Buffer[1];
	GainPreset = GainPreset & 0b11100111;

	switch (scale) {
	case 5:
		if (verbose)
		printf("Scale 0.5 \n");
		Gain = 0;
		Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 25:
		if (verbose)
		printf("Scale 0.25 \n");
		Gain = 0b01;
		Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 125:
		if (verbose)
		printf("Scale 0.125 \n");
		Gain = 0b10;
		Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	default:
		exit(1);
		break;
	}


	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	Buffer[1] = GainPreset;

	ade7763ReadWrite(SPI1, Buffer, SPIWRITE, 0);
}

/**
 * @brief Nastaví vstupní zesílení proudového převodníku PGA1 0,2,4,8,16x.
 * @param GainSet Výběr zesílení PGA 0,2,4,8 a 16.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  nome
 */
void SetGainPGA17763(uint8_t GainSet, uint8_t verbose) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint8_t GainPreset;
	uint8_t Gain;

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	GainPreset = Buffer[1];
	GainPreset = GainPreset & 0b11111000;

	switch (GainSet) {
	case 1:
		if (verbose)
		printf("Gain PGA1 1\n");
		Gain = 0;
		//Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 2:
		if (verbose)
		printf("Gain PGA1 2\n");
		Gain = 0b001;
		//Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 4:
		if (verbose)
		printf("Gain PGA1 4\n");
		Gain = 0b010;
		//Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 8:
		if (verbose)
		printf("Gain PGA1 8\n");
		Gain = 0b011;
		//Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;
	case 16:
		if (verbose)
		printf("Gain PGA1 16\n");
		Gain = 0b100;
		//Gain = Gain << 3;
		GainPreset = GainPreset + Gain;
		break;

	default:
		exit(1);
		break;
	}


	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	Buffer[1] = GainPreset;

	ade7763ReadWrite(SPI1, Buffer, SPIWRITE, 0);
}


/**
 * @brief Nastaví vstupní zesílení proudového převodníku PGA2 0,2,4,8,16x.
 * @param GainSet Výběr zesílení PGA 0,2,4,8 a 16.
 * @return  nome
 */
void SetGainPGA27763(uint8_t GainSet) {
	uint8_t Buffer[MaxBuffSize];
	uint8_t i;
	uint8_t GainPreset;
	uint8_t Gain;

	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	ade7763ReadWrite(SPI1, Buffer, SPIREAD, 0);

	GainPreset = Buffer[1];
	GainPreset = GainPreset & 0b00011111;

	switch (GainSet) {
	case 1:
		Gain = 0;
		//Gain = Gain << 5;
		GainPreset = GainPreset + Gain;
		break;
	case 2:
		Gain = 0b00100000;
		//Gain = Gain << 5;
		GainPreset = GainPreset + Gain;
		break;
	case 4:
		Gain = 0b01000000;
		//Gain = Gain << 5;
		GainPreset = GainPreset + Gain;
		break;
	case 8:
		Gain = 0b01100000;
		//Gain = Gain << 5;
		GainPreset = GainPreset + Gain;
		break;
	case 16:
		Gain = 0b10000000;
		//Gain = Gain << 5;
		GainPreset = GainPreset + Gain;
		break;

	default:
		exit(1);
		break;
	}


	CLEAN_POLE(MaxBuffSize, Buffer);
	Buffer[0] = ADRGAIN;
	Buffer[1] = GainPreset;

	ade7763ReadWrite(SPI1, Buffer, SPIWRITE, 0);
}

/**
 * @brief Vypíše naměřenou a zprůměrovanou hodnotu proudu  Irms [A].
 * Funkce obsahuje Autoscale.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  Vrací změřenou hodnoty proudu.
 */
float GetAutoIrms7763(uint8_t verbose) {


			float IrmsNaBocniku;
			float Irms;
			float IrmsPrum = 0;
			float temp_irms =0;
		    static T_kruh_buffer Struct_Irms;
		    uint8_t i;


			if (!(GetFrequency7763(NON_VERBOSE_MODE) > 45 && GetFrequency7763(NON_VERBOSE_MODE) < 65) ) // když je bez napětí je detekovaná frekvence hodně velká (šum) tato podmínka zruší měření v takovémto případě.
						{
						if (verbose)
								{
						printf("Vrms 0 V\n");
							printf("Frekvence napětí mimo rozsah \n");
								}
						else
						printf("0\n");

						return (0);
						} // konec detekce je na napětí připojeno respektive je-li frekvence v mezích



			SetScalePGA17763(5, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE,FAST);

	if (IrmsPrum < IRMSMAXSCALE125) {

		SetScalePGA17763(125, VERBOSE_MODE);

		if (IrmsPrum < IRMSMAXSCALE125G16) {
			SetGainPGA17763(16, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE, NON_FAST);
			IrmsNaBocniku = ((IRMSINSCALE125/16) / IRMSMAXSCALE5) * IrmsPrum + IRMSHRARDOFFSETSCALE125G16;

		} else if (IrmsPrum < IRMSMAXSCALE125G8) {
			SetGainPGA17763(8, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE, NON_FAST);
			IrmsNaBocniku = ((IRMSINSCALE125/8) / IRMSMAXSCALE5) * IrmsPrum + IRMSHRARDOFFSETSCALE125G8;

		} else if (IrmsPrum < IRMSMAXSCALE125G4) {
			SetGainPGA17763(4, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE, NON_FAST);
			IrmsNaBocniku = ((IRMSINSCALE125/4) / IRMSMAXSCALE5) * IrmsPrum + IRMSHRARDOFFSETSCALE125G4;

		} else if (IrmsPrum < IRMSMAXSCALE125G2) {
			SetGainPGA17763(2, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE, NON_FAST);
			IrmsNaBocniku = ((IRMSINSCALE125/2) / IRMSMAXSCALE5) * IrmsPrum + IRMSHRARDOFFSETSCALE125G2;

		} else //(IrmsPrum < IRMSMAXSCALE125G1)
			{
			SetGainPGA17763(1, VERBOSE_MODE);
			IrmsPrum = GetIrms7763(NON_VERBOSE_MODE, NON_FAST);
			IrmsNaBocniku = IRMSINSCALE125 / IRMSMAXSCALE5 * IrmsPrum+ IRMSHRARDOFFSET;
		}

	}
			else if (IrmsPrum < IRMSMAXSCALE25 )
			{
				SetScalePGA17763(25, VERBOSE_MODE);
				IrmsPrum = GetIrms7763(NON_VERBOSE_MODE,NON_FAST);
				IrmsNaBocniku = IRMSINSCALE25 / IRMSMAXSCALE5 * IrmsPrum + IRMSHRARDOFFSET;
			}
			else  //IRMSMAXSCALE5
			{
				SetScalePGA17763(5, VERBOSE_MODE);
				IrmsNaBocniku = IRMSINSCALE5 / IRMSMAXSCALE5 * IrmsPrum + IRMSHRARDOFFSET  ; //maximální vstupní napětí / počtem hladin * naměřená hodnota
			}



			Irms = (IrmsNaBocniku/RBOCNIK)/5;

			//následuje průměrování, aktuální změřená hodnota se vezme a uloží do kruhového bufferu 200 prvků.
			Struct_Irms.Prum_pole[Struct_Irms.pozice] = Irms;
			for (i=0;i<POCETPRUMEROVACICHCIKLU;i++)
			{
				temp_irms = temp_irms + Struct_Irms.Prum_pole[i];
			}
			Irms = temp_irms / POCETPRUMEROVACICHCIKLU;

			if (Struct_Irms.pozice < POCETPRUMEROVACICHCIKLU)
				Struct_Irms.pozice ++;
			else
				Struct_Irms.pozice = 0;

			// konec průměrování


			if (verbose)
				printf("Irms %f A \n", Irms);
			else
				printf("%f\n", Irms);

	return (Irms);
	}

/**
 * @brief Vypíše naměřenou a zprůměrovanou hodnotu proudu  Irms [A].
 * Funkce obsahuje Autoscale.
 * @param verbose Pro 1 podá rozšířený textový výstup, pro 0 základní textový výstup.
 * @return  Vrací změřenou hodnoty proudu.
 */
float fakewatt(float proud, float napeti){
	return (proud*napeti);
}
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

